<template>
  <div class="carousel-item-container" @mousemove="handleMouseMove" @mouseleave="handleMouseLeave" ref="carouselRef">
    <div class="carousel-img" ref="image" :style="imagePosition">
      <ImageLoader :src="carousel.bigImg" :placeholder="carousel.midImg" @load="this.showWords" />
    </div>

    <div class="title" ref="titleRef">{{ carousel.title }}</div>
    <div class="desc" ref="descRef">{{ carousel.description }}</div>
  </div>
</template>

<script>
import ImageLoader from '@/components/ImageLoader'

export default {
  name: 'CarouselItem',
  components: { ImageLoader },
  props: ['carousel'],
  data() {
    return {
      titleWidth: 0,
      descWidth: 0,
      containerSize: null, // 外层容器的尺寸
      innerSize: null, // 里层图片的尺寸
      mouseX: 0, // 鼠标的横坐标
      mouseY: 0, // 鼠标的纵坐标
    }
  },
  computed: {
    imagePosition() {
      if (!this.containerSize || !this.innerSize) return
      const extraWidth = this.innerSize.width - this.containerSize.width
      const extraHeight = this.innerSize.height - this.containerSize.height
      const left = (-extraWidth / this.containerSize.width) * this.mouseX
      const top = (-extraHeight / this.containerSize.height) * this.mouseY
      return {
        transform: `translate(${left}px, ${top}px)`,
      }
    },
    center() {
      return {
        x: this.containerSize.width / 2,
        y: this.containerSize.height / 2,
      }
    },
  },
  mounted() {
    this.titleWidth = this.$refs.titleRef.clientWidth
    this.descWidth = this.$refs.descRef.clientWidth
    this.setSize()
    this.mouseX = this.center.x
    this.mouseY = this.center.y
    window.addEventListener('resize', this.setSize)
  },
  destroyed() {
    window.removeEventListener('resize', this.setSize)
  },
  methods: {
    showWords() {
      this.$refs.titleRef.style.opacity = 1
      this.$refs.titleRef.style.width = 0
      this.$refs.titleRef.clientHeight
      this.$refs.titleRef.style.transition = '1s'
      this.$refs.titleRef.style.width = this.titleWidth + 'px'

      this.$refs.descRef.style.opacity = 1
      this.$refs.descRef.style.width = 0
      this.$refs.descRef.clientHeight
      this.$refs.descRef.style.transition = '2s 1s'
      this.$refs.descRef.style.width = this.descWidth + 'px'
    },
    setSize() {
      this.containerSize = {
        width: this.$refs.carouselRef.clientWidth,
        height: this.$refs.carouselRef.clientHeight,
      }

      this.innerSize = {
        width: this.$refs.image.clientWidth,
        height: this.$refs.image.clientHeight,
      }
    },
    handleMouseMove(e) {
      const rect = this.$refs.carouselRef.getBoundingClientRect()
      this.mouseX = e.clientX - rect.left
      this.mouseY = e.clientY - rect.top
    },
    handleMouseLeave() {
      this.mouseX = this.center.x
      this.mouseY = this.center.y
    },
  },
}
</script>

<style scoped lang="less">
@import '~@/styles/var.less';
.carousel-item-container {
  width: 100%;
  height: 100%;
  color: #fff;
  position: relative;
  overflow: hidden;
  .carousel-img {
    width: 110%;
    height: 100%;
    position: absolute;
    left: 0;
    top: 0;
    transition: 0.3s;
  }
  .title,
  .desc {
    position: absolute;
    letter-spacing: 3px;
    white-space: nowrap;
    left: 30px;
    color: #fff;
    text-shadow: 1px 0 0 rgba(0, 0, 0, 0.5), -1px 0 0 rgba(0, 0, 0, 0.5), 0 1px 0 rgba(0, 0, 0, 0.5), 0 -1px 0 rgba(0, 0, 0, 0.5);
    overflow: hidden;
    opacity: 0;
  }
  .title {
    top: calc(50% - 40px);
    font-size: 2em;
  }
  .desc {
    top: calc(50% + 20px);
    font-size: 1.2em;
    color: lighten(@gray, 20%);
  }
}
</style>
